<?php

declare(strict_types=1);

namespace App\Middleware;

use App\Constants\Common\ApiStatusEnum;
use App\Constants\User\UserStatusEnum;
use App\Service\Access\UserAccess;
use Hyperf\Context\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\HttpMessage\Stream\SwooleStream;

/**
 * 用户登录凭证验证-中间件
 */
class UserAuthorizationMiddleware implements MiddlewareInterface
{
        /**
         * 过程处理
         * @param ServerRequestInterface $request
         * @param RequestHandlerInterface $handler
         * @return ResponseInterface
         */
	public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
	{
		$response = Context::get(ResponseInterface::class);
		$strAuthorization = $request->getHeaderLine('Authorization');
		$strAuthorization = str_replace('Bearer ', '', $strAuthorization);
                $jsonReturn = json_encode(businessError(ApiStatusEnum::UNAUTHORIZED->getMessage(),
                        ApiStatusEnum::UNAUTHORIZED->value), JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
		if (!$strAuthorization) {
			return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
				->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
		}
		$jsonAuthorization = customizeEncryptDecrypt($strAuthorization, 2);
		if (!$jsonAuthorization) {
			return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
				->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
		}
		$arrAuthorization = json_decode($jsonAuthorization, true);
		if (!$arrAuthorization) {
			return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
				->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
		}
                if (isset($arrAuthorization['userAgent']) && $request->getHeaderLine('user-agent') !== $arrAuthorization['userAgent']) {
                        return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
                                ->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
                }
                if (isset($arrAuthorization['referer']) && $request->getHeaderLine('referer') !== $arrAuthorization['referer']) {
                        return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
                                ->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
                }
		$request = $request->withAttribute('userId', $arrAuthorization['userId']);
		$request = Context::set(ServerRequestInterface::class, $request);
		$arrUser = (new UserAccess())->find($arrAuthorization['userId'], ['status', 'password', 'loginFinallyTime']);
		if ($arrUser['status'] !== UserStatusEnum::DEFINITION_1->value) {
			return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
				->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
		}
		if ($arrUser['password'] !== $arrAuthorization['password']) {
			return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
				->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
		}
                /*if ($arrUser['loginFinallyTime'] !== $arrAuthorization['loginFinallyTime']) {
                        return $response->withHeader('Content-Type', $request->getHeader('content-type')[0] ?? 'application/json;charset=utf-8')
                                ->withStatus(ApiStatusEnum::UNAUTHORIZED->value)->withBody(new SwooleStream($jsonReturn));
                }*/
		return $handler->handle($request);
	}
}